﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GCTrackableRace.Interfaces;
using log4net;
using System.IO;

namespace GcTrackableRace.Persistence
{
	public class ScoreTabFilePersistence: IScorePersistance
	{
		public ScoreTabFilePersistence(ILog log)
		{
			Log = log;
		}

		public void PersistTrackableScores(IEnumerable<ITrackable> trackables, IProgramConfigurationSettings programConfigurationSettings)
		{
			var tabText = GenerateTabText(trackables);

			PersistCsvText(tabText, programConfigurationSettings);
		}

		private ILog Log { get; set; }

		#region Private Methods

		private static string GenerateTabText(IEnumerable<ITrackable> trackables)
		{
			var sb = new StringBuilder();

			sb.AppendLine(CreatedTabHeaders(trackables.First()));

			foreach (var trackable in trackables.OrderBy(t => t.Name))
			{
				var scoreDetials = GetScoreDetails(trackable);

				sb.AppendLine(String.Format("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}",
					trackable.Name,
					trackable.Code,
					trackable.Owner,
					trackable.Country,
					trackable.State,
					trackable.County,
					trackable.TrackableType,
					scoreDetials));
			}

			return sb.ToString();
		}

		private static void PersistCsvText(string csvText, IProgramConfigurationSettings programConfigurationSettings)
		{
			var fileNameAndPath = programConfigurationSettings.GetOutputFileNameAndLocation(FileType.TabScoreAtEndRaceResultTextFile);

			if (File.Exists(fileNameAndPath))
				File.Delete(fileNameAndPath);

			if (!Directory.Exists(programConfigurationSettings.OutputDirectory))
				Directory.CreateDirectory(programConfigurationSettings.OutputDirectory);

			File.WriteAllText(fileNameAndPath, csvText);
		}

		private static string CreatedTabHeaders(ITrackable trackable)
		{
			var sb = new StringBuilder();

			sb.Append("Name\tCode\tOwner\tFrom-Country\tFrom-State\tFrom-County\tTrackableType\t");

			foreach (var ruleScore in trackable.RuleScores)
			{
				sb.Append(String.Format("{0}-Count\t{0}-Score\t{0}-Detail\t", ruleScore.ReportColumnName));
			}

			return sb.ToString();
		}

		private static object GetScoreDetails(ITrackable trackable)
		{
			var sb = new StringBuilder();

			foreach (var ruleScore in trackable.RuleScores)
			{
				sb.Append(String.Format("{0}\t{1}\t{2}\t", ruleScore.Count, ruleScore.Score, ruleScore.ScoreDetails));
			}

			return sb.ToString();
		}

		#endregion Private Methods
	}
}